import Cocoa

//var str = "Hello, playground"

/**
 Swift中有下面这些模式:
 1. 通配符模式（Wildcard Pattern）
 2. 标识符模式（Identifier Pattern）
 3. 值绑定模式 (Value-Binding Pattern）
 4. 元组模式 (Tuple Pattern）
 5. 可选项模式 （Optional Pattern）
 6. 枚举用例模式 （Enumeration Case Pattern）
 7. 类型转换模式 （Type-Casing Pattern）
 8. 表达式模式 （Expression Pattern）
 */

//1. 通配符模式:有一个下划线(_)组成,用来匹配并忽略任何值
var sum = 1
let base = 3
for _ in 1...5 {
    sum *= base   //获取3的5次方
}
print(sum)

//2. 标识符模式: 标识符模式匹配任何值,并将匹配的值和一个常量或者变量绑定起来
//let name: String = "张三"  //将张三和name这个常量绑定起来
//let numer = 2  //将2和number这个常量绑定起来

//3. 值绑定模式:把匹配到的值绑定给一个变量或常量
let num = (1, 2)
switch num {
case let (x, y):
    print("x is \(x), y is \(y)")
//default:      //因为前面的条件已经满足了,这个方法永远不会执行.所以这个default可以省略
//    print("no number")
}

//4. 元组模式:由逗号分隔,具有零个或多个模式的列表,并由一对圆括号括起来
//(5, 2)

//5. 可选项模式: 可选项用"?"表示,可选项模式为for in语句提供了一种迭代数组的简便方式,只为数组中非nil的元素执行循环体
//let someOptional: Int? = 42
//if case let x? = someOptional {   //在case中定义一个可选项的值赋值给一个可选项,可以直接获取新定义的这个可选项的值
//    print(x)
//}

//或者用枚举的some属性来创建可选项值
let someOptional: Int? = 42
if case .some(let x) = someOptional {
    print(x)
}


let arrayOptionalInt: [Int?] = [2, nil, 3, 6, nil, 0]
for case let number? in arrayOptionalInt {   //只为数组中非nil的元素执行循环体
    print("found a \(number)")
}

//6. 枚举模式: 匹配现有的某个枚举的某个用例。枚举用例模式出现在switch语句中的case标签中，以及if、while、guard和for-in语句的case条件中。
public enum AnimalTransition: Int {
    case none
    case flipFromLeft
    case flipFromRight
    case curlUp
    case curlDown
}

//7. 类型转换模式: 有两种类型转换模式，is模式和as模式。is模式只出现在switch语句中的case标签中。形式如下
//is 类型：is模式仅当一个值的类型在运行时和is模式右边的指定类型一致，或者是其子类的情况下，才会匹配这个值。is模式没有返回类型
//模式 as 类型：as模式仅当一个值的类型在运行时和as模式右边的指定类型一致，或者是其子类的情况下，才会匹配这个值。如果匹配成功，被匹配的值的类型

protocol Animal {
    var name: String { get }
}

struct Dog: Animal {
    var name: String {
        return "dog"
    }
    var runSpeed: Int
}

struct Bird: Animal {
    var name: String {
        return "bird"
    }
    var flightHieht: Int
}

struct Fish: Animal {
    var name: String {
        return "fish"
    }
    var depth: Int
}

let animals: [Any] = [Dog(runSpeed: 55), Bird(flightHieht: 2000), Fish(depth: 100)]
for animal in animals {
    switch animal {
    case let dog as Dog: //as右边的指定类型 Dog 和运行时的类型 dog一致
        print("\(dog.name) can run \(dog.runSpeed)")
    case let bird as Bird:
        print("\(bird.name) can fly \(bird.flightHieht)")
    case is Fish:  //is 右边的指定类型 Fish 和 运行时的类型 fish 一致，注意： is没有返回类型
        print("fish can swimming")
    default:
        print("unknow animals")
    }
}

//8. 表达式模式: 表达式的值，只出现在switch语句的case标签中。表达式模式代表的表达式会使用~=运算符与输入表达式的值进行比较。~=运算符可以查看一个范围是否包含某个值，如果~=运算符返回true，则匹配成功。
//let point = (1, 2)
//switch point {
//case (0, 0):
//    print("point在圆点")
//case (-2...2, -2...2):
//    print("(\(point.0), \(point.1)) is near the origin")
//default:
//    print("no one point")
//}

//使用重载 ~= 运算符来提供自定义的表达式的行为
//~=运算符可以查看一个范围是否包含某个值，如果~=运算符返回true，则匹配成功。
let point = (1, 2)
//func ~= (pattern: String, value: Int) -> Bool {
//    print("\(pattern), \(value)")
//    return pattern == "\(value)"
//}
switch point {
case (0, 0):
    print("point在圆点")
default:
    print("the point is at (\(point.0), \(point.1))")
}

struct Employee {
    var salary: Float
}
let e = Employee(salary: 9999)
func ~= (left: Range<Float>, right: Employee) -> Bool {
    print("\(left), \(right)")
    return left.contains(right.salary) //查看一个范围是否包含某个值，如果~=运算符返回true，则匹配成功。
}
switch  e{
case 0.0..<1000:
    print("艰难生活")
case 1000..<5000:
    print("小康社会")
case 5000..<10000:
    print("生活的很滋润")
default:
    break
}

